package com.dog.modules.iot.config;

import com.dog.framework.core.constant.IotMqConstants;
import org.springframework.amqp.core.AbstractExchange;
import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;



/**
 */
@Configuration
public class MqttRabbitConfig {

    @Autowired
    private AmqpAdmin amqpAdmin;

    /**
     * 针对消费者配置
     * 1. 设置交换机类型
     * 2. 将队列绑定到交换机
     * FanoutExchange: 将消息分发到所有的绑定队列，无routingkey的概念
     * HeadersExchange ：通过添加属性key-value匹配
     * DirectExchange:按照routingkey分发到指定队列
     * TopicExchange:多关键字匹配
     */
    @Bean(name = "cleaningDirectExchange")
    public DirectExchange directExchange() {
        DirectExchange exchange = new DirectExchange(IotMqConstants.CLEANING_DIRECT_EXCHANGE);
        addExchange(exchange);
        return exchange;
    }

    //    @Bean(name = "fanoutExchange")
    public FanoutExchange fanoutExchange() {
        FanoutExchange exchange = new FanoutExchange(IotMqConstants.CLEANING_FANOUT_EXCHANGE);
        addExchange(exchange);
        return exchange;
    }

    @Bean(name = "cleaningRobotMsgQueue0")
    public Queue queue0() {
        //队列持久
        Queue queue0 = new Queue(IotMqConstants.CLEANING_ROBOT_MSG_QUEUE_0, true);
        addQueue(queue0);
        addBinding(queue0, directExchange(), IotMqConstants.CLEANING_ROBOT_MSG_ROTING_KEY_0);
        return queue0;
    }

    @Bean(name = "cleaningRobotMsgQueue1")
    public Queue queue1() {
        //队列持久
        Queue queue0 = new Queue(IotMqConstants.CLEANING_ROBOT_MSG_QUEUE_1, true);
        addQueue(queue0);
        addBinding(queue0, directExchange(), IotMqConstants.CLEANING_ROBOT_MSG_ROTING_KEY_1);
        return queue0;
    }

    @Bean(name = "cleaningRobotMsgQueue2")
    public Queue queue2() {
        //队列持久
        Queue queue0 = new Queue(IotMqConstants.CLEANING_ROBOT_MSG_QUEUE_2, true);
        addQueue(queue0);
        addBinding(queue0, directExchange(), IotMqConstants.CLEANING_ROBOT_MSG_ROTING_KEY_2);
        return queue0;
    }

    @Bean(name = "cleaningRobotMsgQueue3")
    public Queue queue3() {
        //队列持久
        Queue queue0 = new Queue(IotMqConstants.CLEANING_ROBOT_MSG_QUEUE_3, true);
        addQueue(queue0);
        addBinding(queue0, directExchange(), IotMqConstants.CLEANING_ROBOT_MSG_ROTING_KEY_3);
        return queue0;
    }

    @Bean(name = "cleaningRobotMsgQueue4")
    public Queue queue4() {
        //队列持久
        Queue queue0 = new Queue(IotMqConstants.CLEANING_ROBOT_MSG_QUEUE_4, true);
        addQueue(queue0);
        addBinding(queue0, directExchange(), IotMqConstants.CLEANING_ROBOT_MSG_ROTING_KEY_4);
        return queue0;
    }

    @Bean(name = "cleaningRobotMsgQueue5")
    public Queue queue5() {
        //队列持久
        Queue queue0 = new Queue(IotMqConstants.CLEANING_ROBOT_MSG_QUEUE_5, true);
        addQueue(queue0);
        addBinding(queue0, directExchange(), IotMqConstants.CLEANING_ROBOT_MSG_ROTING_KEY_5);
        return queue0;
    }

    @Bean(name = "cleaningRobotMsgQueue6")
    public Queue queue6() {
        //队列持久
        Queue queue0 = new Queue(IotMqConstants.CLEANING_ROBOT_MSG_QUEUE_6, true);
        addQueue(queue0);
        addBinding(queue0, directExchange(), IotMqConstants.CLEANING_ROBOT_MSG_ROTING_KEY_6);
        return queue0;
    }

    @Bean(name = "cleaningRobotMsgQueue7")
    public Queue queue7() {
        //队列持久
        Queue queue0 = new Queue(IotMqConstants.CLEANING_ROBOT_MSG_QUEUE_7, true);
        addQueue(queue0);
        addBinding(queue0, directExchange(), IotMqConstants.CLEANING_ROBOT_MSG_ROTING_KEY_7);
        return queue0;
    }

    @Bean(name = "cleaningRobotMsgQueue8")
    public Queue queue8() {
        //队列持久
        Queue queue0 = new Queue(IotMqConstants.CLEANING_ROBOT_MSG_QUEUE_8, true);
        addQueue(queue0);
        addBinding(queue0, directExchange(), IotMqConstants.CLEANING_ROBOT_MSG_ROTING_KEY_8);
        return queue0;
    }

    @Bean(name = "cleaningRobotMsgQueue9")
    public Queue queue9() {
        //队列持久
        Queue queue0 = new Queue(IotMqConstants.CLEANING_ROBOT_MSG_QUEUE_9, true);
        addQueue(queue0);
        addBinding(queue0, directExchange(), IotMqConstants.CLEANING_ROBOT_MSG_ROTING_KEY_9);
        return queue0;
    }


    @Bean(name = "queueSanIot")
    public Queue queueIotIn() {
        //队列持久
        Queue queue0 = new Queue(IotMqConstants.CLEANING_IOT_IN_QUEUE, true);
        addQueue(queue0);
        addBinding(queue0, directExchange(), IotMqConstants.CLEANING_IOT_IN_ROUTING_KEY);
        return queue0;
    }

    @Bean(name = "queueSanOut")
    public Queue queueIotOut() {
        Queue queue1 = new Queue(IotMqConstants.CLEANING_IOT_OUT_QUEUE, true);
        addQueue(queue1);
        addBinding(queue1, directExchange(), IotMqConstants.CLEANING_IOT_OUT_ROUTING_KEY);
        return queue1;
    }


//  ------ 动态创建和绑定，无需在管理平台手动创建 ------

    /**
     * 创建Exchange
     *
     * @param exchange
     */
    private void addExchange(AbstractExchange exchange) {
        amqpAdmin.declareExchange(exchange);
    }

    /**
     * 创建一个指定的Queue
     *
     * @param queue
     * @return queueName
     */
    private String addQueue(Queue queue) {
        return amqpAdmin.declareQueue(queue);
    }

    /**
     * 绑定一个队列到一个匹配型交换器使用一个routingKey
     *
     * @param queue
     * @param exchange
     * @param routingKey
     */
    private void addBinding(Queue queue, DirectExchange exchange, String routingKey) {
        Binding binding = BindingBuilder.bind(queue).to(exchange).with(routingKey);
        amqpAdmin.declareBinding(binding);
    }

    private void addBinding(Queue queue, FanoutExchange exchange) {
        Binding binding = BindingBuilder.bind(queue).to(exchange);
        amqpAdmin.declareBinding(binding);
    }

}
